Skip to content

Doc: clarify priority of lint level sources #142021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

HamidrezaSK
Copy link

@HamidrezaSK HamidrezaSK commented Jun 4, 2025

This updates the rustc book to clearly document how conflicting lint configurations are resolved across different sources, including command-line flags, crate-level attributes, in-line attributes, and --cap-lints.

It also explains the special behavior of forbid and force_warn.

Fixes #124088

@rustbot
Copy link
Collaborator

rustbot commented Jun 4, 2025

r? @ehuss

rustbot has assigned @ehuss.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 4, 2025
@rust-log-analyzer

This comment has been minimized.


## Priority of Lint Level Sources

Rust allows setting lint levels (`allow`, `warn`, `deny`, etc.) through various sources: directly in the code, via command-line flags, or through global compiler configuration. When these sources conflict, the compiler follows a well-defined priority order to determine which setting takes effect.
Copy link
Member

@jieyouxu jieyouxu Jun 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some general remarks (I don't have bandwidth to take over review for this ATM):

  • I wonder if we should explicitly delineate between lint level control mechanisms which are compiler-only, versus those part of the language (such as in-source lint level attributes).
  • I'm not so sure the priority order is well-defined. See Support overriding warnings level for a specific lint via command line #113307 (comment).
  • Note that the ordering of compiler flags can matter! Some flags are "commutative" (in terms of observable final behavior) with respect to each other IIRC, while some flags aren't.
  • (Unstable, not suitable for stable rustc book) there's also the --crate-attr flag, which can somewhat blur the line between compiler vs language.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! I took a closer look and I think you're right. If that's the case, it might be best to just document the ordering for in-source lint level attributes, where the behavior is straightforward: the closer attribute takes precedence.

@jieyouxu jieyouxu added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools labels Jun 4, 2025
Copy link
Contributor

@ehuss ehuss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Looks like there is a CI error that needs to be resolved.


## Priority of Lint Level Sources

Rust allows setting lint levels (`allow`, `warn`, `deny`, etc.) through various sources: directly in the code, via command-line flags, or through global compiler configuration. When these sources conflict, the compiler follows a well-defined priority order to determine which setting takes effect.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a "global compiler configuration"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Poor wording on my side, I meant options in the .cargo file, which is the same as CLI options, so I removed this part.


Rust allows setting lint levels (`allow`, `warn`, `deny`, etc.) through various sources: directly in the code, via command-line flags, or through global compiler configuration. When these sources conflict, the compiler follows a well-defined priority order to determine which setting takes effect.

This section explains how Rust resolves conflicts between **different sources of lint configuration**, rather than between the lint levels themselves.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wording nit:

Suggested change
This section explains how Rust resolves conflicts between **different sources of lint configuration**, rather than between the lint levels themselves.
This section explains how conflicts are resolved between **different sources of lint configuration**, rather than between the lint levels themselves.


This section explains how Rust resolves conflicts between **different sources of lint configuration**, rather than between the lint levels themselves.

### Priority of Sources (Highest to Lowest)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually use sentence case for section titles.

Suggested change
### Priority of Sources (Highest to Lowest)
### Priority of sources (highest to lowest)

Comment on lines 345 to 346
in-line attributes (#[...]) >
crate-level attributes (#![...]) >
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the way this is presented is possibly confusing. The language doesn't differentiate between inner and outer attributes for lint levels. It just so happens that crate-level can only be specified by an inner attribute. But inner attributes can show up in many places. I would probably just say "attributes" here, since attributes just create an AST-hierarchy with the most-specific taking precedence.

command-line flags (-A, -W, -D)
```

### Special Cases
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Special Cases
### Special case priorities


### Special Cases

The special levels `forbid(lint)` and `force_warn(lint)` take precedence over normal configurations **regardless of where they are set**.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of parentheses looks a little strange here to me, since force_warn(lint) isn't a valid syntax anywhere. How about just something like this?

Suggested change
The special levels `forbid(lint)` and `force_warn(lint)` take precedence over normal configurations **regardless of where they are set**.
The special levels forbid and force-warn take precedence over normal configurations **regardless of where they are set**.

I don't know what "normal configurations" are.

Also, this doesn't seem quite accurate to me. cap-lints takes precedence over forbid.
And in a sense it does matter where forbid is set, since it applies only to the AST-hierarchy below where it is set.

force-warn can only be set in one place (the CLI), though I'm not sure if this is trying to convey something about the order of CLI arguments?

This doesn't say how forbid and force-warn interact with one another.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a bit confusing for me. As far as I understood, for allow, deny, and warn whoever has the most-specific scope takes precedence. However, it is the opposite case for forbid and force-warn.

Even the ordering in the cli options, as mentioned in the book, for -A, -D, and -W which ever option comes last, takes place, but for --force-warn and -F which ever option comes first, takes place.

@HamidrezaSK HamidrezaSK force-pushed the fix-lint-precedence-doc branch from bb04e82 to 6e8d426 Compare June 6, 2025 20:53
@rust-log-analyzer

This comment has been minimized.

@HamidrezaSK HamidrezaSK force-pushed the fix-lint-precedence-doc branch from 6e8d426 to 3cf81db Compare June 6, 2025 21:49
@rust-log-analyzer

This comment has been minimized.

@HamidrezaSK HamidrezaSK force-pushed the fix-lint-precedence-doc branch from 3cf81db to d6603df Compare June 6, 2025 22:32
@rust-log-analyzer

This comment has been minimized.

This updates the rustc book to clearly document how conflicting lint configurations are resolved across different sources, including command-line flags, crate-level attributes, in-line attributes, and `--cap-lints`.

It also explains the special behavior of `forbid` and `force_warn`.
@HamidrezaSK HamidrezaSK force-pushed the fix-lint-precedence-doc branch from d6603df to e097fd1 Compare June 7, 2025 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

rustc book does not specify priority between lint options like -A and attributes
5 participants